package lt.ntec.danblog.server.blog;

import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;

import lt.ntec.danblog.server.blog.model.Post;
import lt.ntec.danblog.server.blog.model.PostDAO;
import lt.ntec.danblog.server.blog.util.PostUtils;
import lt.ntec.danblog.server.core.model.Comment;
import lt.ntec.danblog.server.core.model.Tag;
import lt.ntec.danblog.server.core.model.TagDAO;
import lt.ntec.danblog.server.core.model.User;
import lt.ntec.danblog.server.core.validator.Validable;
import lt.ntec.danblog.server.core.validator.ValidationException;
import com.google.inject.Inject;
import lt.ntec.danblog.server.blog.model.PostFactory;
import lt.ntec.danblog.server.core.model.CommentFactory;
import lt.ntec.danblog.server.core.model.TagFactory;

public class BlogService implements Service {

    private PostDAO dao;
    private TagDAO tagDao;
    private User user;
    private TagFactory tagFactory;
    private PostFactory postFactory;
    private CommentFactory commentFactory;

    @Inject
    BlogService(PostDAO postDao, TagDAO tagDao, User user, TagFactory tagFactory, PostFactory postFactory, CommentFactory commentFactory) {
        this.dao = postDao;
        this.tagDao = tagDao;
        this.user = user;
        this.tagFactory = tagFactory;
        this.postFactory = postFactory;
        this.commentFactory = commentFactory;
    }

    @Override
    public Long createPost(String title, String content, String tag)
            throws ValidationException {

        Post post = postFactory.createPost(this.user, (PostUtils.generateUrlString(title)
                + "." + DOCUMENT_FIELD_ENDING));

        post.setTitle(title);
        dao.save(post);
        post.setTags(processTags(tag, post));

        post.setDate(new Date());
        post.setContent(content);

        Validable validator = new PostValidator();
        if (!validator.isValid(post)) {
            throw new PostValidator.PostValidationException(
                    validator.getMessages());
        }

        return dao.save(post);
    }

    @Override
    public void deletePost(Long id) {
        this.dao.delete(id);
    }

    private Set<Tag> processTags(String tagString, Post post) {
        List<String> tags = Arrays.asList(tagString.split("\\ "));
        Set<Tag> tr = new TreeSet<Tag>();
        for (String tg : tags) {
            Tag etag = tagDao.getTagByValue(tg);
            if (etag == null) {
                etag = tagFactory.createTag(tg, post);
                tagDao.save(etag);
            }
            tr.add(etag);
        }
        return tr;
    }

    @Override
    public void updatePost(Long id, String title, String content, String tag)
            throws BlogServiceException, ValidationException {

        Post post = dao.getById(id);

        post.setTags(processTags(tag, post));
        post.setContent(content);
        post.setTitle(title);

        Validable validator = new PostValidator();
        if (!validator.isValid(post)) {
            throw new PostValidator.PostValidationException(
                    validator.getMessages());
        }

        dao.save(post);

    }

    @Override
    public Long addComment(Long id, String content)
            throws BlogServiceException, ValidationException {

        Post post = dao.getById(id);

        Comment comment = commentFactory.createComment(this.user, post);
        comment.setContent(content);
        comment.setDate(new Date());

        post.addComment(comment);
        dao.save(post);

        return comment.getId();
    }
}
